<script setup lang="ts">
import type { AttachmentsProps } from 'ant-design-x-vue'
import {
  CloudUploadOutlined,
  PaperClipOutlined,
} from '@ant-design/icons-vue'
import { Badge, Button, Flex, Typography, theme } from 'ant-design-vue'
import {
  Attachments,
  Sender,
} from 'ant-design-x-vue'
import { computed, ref } from 'vue'

interface Props {
  value: string
  loading?: boolean
}

interface Emits {
  submit: [content: string]
  change: [value: string]
}

const props = withDefaults(defineProps<Props>(), {
  loading: false
})

const emit = defineEmits<Emits>()

const { token } = theme.useToken()

const headerOpen = ref(false)
const attachedFiles = ref<AttachmentsProps['items']>([])

const styles = computed(() => {
  return {
    sender: {
      'box-shadow': token.value.boxShadow,
    },
  } as const
})

const handleSubmit = (content: string) => {
  emit('submit', content)
}

const handleChange = (value: string) => {
  emit('change', value)
}

const handleFileChange: AttachmentsProps['onChange'] = (info) => {
  attachedFiles.value = info.fileList
}

const toggleHeader = () => {
  headerOpen.value = !headerOpen.value
}

const handleOpenChange = (open: boolean) => {
  headerOpen.value = open
}
</script>

<template>
  <Sender
    :value="props.value"
    :style="styles.sender"
    :loading="props.loading"
    @submit="handleSubmit"
    @change="handleChange"
  >
    <template #prefix>
      <Badge :dot="attachedFiles.length > 0 && !headerOpen">
        <Button
          type="text"
          @click="toggleHeader"
        >
          <template #icon>
            <PaperClipOutlined />
          </template>
        </Button>
      </Badge>
    </template>

    <template #header>
      <Sender.Header
        title="Attachments"
        :open="headerOpen"
        :styles="{ content: { padding: 0 } }"
        @open-change="handleOpenChange"
      >
        <Attachments
          :before-upload="() => false"
          :items="attachedFiles"
          @change="handleFileChange"
        >
          <template #placeholder="type">
            <Flex
              v-if="type && type.type === 'inline'"
              align="center"
              justify="center"
              vertical
              gap="2"
            >
              <Typography.Text style="font-size: 30px; line-height: 1;">
                <CloudUploadOutlined />
              </Typography.Text>
              <Typography.Title
                :level="5"
                style="margin: 0; font-size: 14px; line-height: 1.5;"
              >
                Upload files
              </Typography.Title>
              <Typography.Text type="secondary">
                Click or drag files to this area to upload
              </Typography.Text>
            </Flex>
            <Typography.Text v-if="type && type.type === 'drop'">
              Drop file here
            </Typography.Text>
          </template>
        </Attachments>
      </Sender.Header>
    </template>
  </Sender>
</template>